import { MenuType, OriginalRouteItem } from "@/typings/hooks/useRoute";
import { useState, useMemo, useEffect, useRef, useCallback } from "react";
import { getCachePermission, getPermissions } from "@/utils";
import { routes } from "@/route";
import { cloneDeep } from "lodash";
import { useLocation } from "react-router";
import { Permission } from "@/typings/api/permission";
export * from "@/typings/hooks/useRoute";

const setIcon = (item: OriginalRouteItem) => {
    if (typeof item.icon === "string") {
        const Icon = require("@ant-design/icons")[item.icon];
        if (Icon) {
            item.icon = <Icon />;
        } else {
            item.icon = null;
        }
    }
};

const formatRoute = (list: OriginalRouteItem[] = []): OriginalRouteItem[] => {
    return list.map(item => {
        setIcon(item);
        if (item.children) {
            if (item.path === "/") return { ...item, children: formatRoute(item.children) };
            return {
                ...item,
                children: formatRoute(
                    item.children.map(child => {
                        if (child.path?.startsWith(item.path)) return child;
                        return { ...child, path: item.path + child.path };
                    })
                ),
            };
        }
        return item;
    });
};

export const useRoute = () => {
    const location = useLocation();
    const initialRoutes = routes.map(item => (item.path === "/" ? { ...item, children: [] } : item));
    const [originRoutes, setOriginRoutes] = useState<OriginalRouteItem[]>(initialRoutes);
    const [permissions, setPermissions] = useState<Permission[]>([]);
    const hasFetch = useRef(false);

    const fetchPermission = useCallback(
        async (realTime = false) => {
            if (location.pathname !== "/login" && !hasFetch.current) {
                const routeList = cloneDeep(routes);
                const rootRoot = routeList.find(item => item.path === "/");
                const res = await getPermissions(realTime);
                const permissionTree = await getCachePermission();
                const permissionList: Permission[] = [];
                const loop = (list: Permission[]) => {
                    list.forEach(item => {
                        loop((item?.children as Permission[]) || []);
                        delete item.children;
                        permissionList.push(item);
                    });
                };
                loop(permissionTree);
                setPermissions(permissionList);
                rootRoot!.children = res;
                setOriginRoutes(routeList);
                hasFetch.current = true;
            }
        },
        [location.pathname]
    );
    useEffect(() => {
        fetchPermission();
    }, [location.pathname]);

    const routesData = useMemo(() => formatRoute(originRoutes), [originRoutes]);
    const menus = useMemo(() => {
        //过滤出非菜单项
        const filterMenu = (list: OriginalRouteItem[] = []): OriginalRouteItem[] => {
            return list.filter(item => item.meta?.type !== "route").map(item => ({ ...item, children: filterMenu(item.children) }));
        };
        const filterMenusResult = filterMenu(routesData.find(item => item.path === "/")?.children);
        //自动生成key、label
        const formatMenu = ({ label, icon, children = [], path }: OriginalRouteItem): MenuType => {
            const menuObj: MenuType = {
                key: path,
                label,
                icon,
            };
            const childrenList = children.map(formatMenu);
            if (childrenList.length) menuObj.children = childrenList;
            return menuObj;
        };
        return filterMenusResult.map(formatMenu);
    }, [routesData]);
    return { routes: routesData, menus, fetch: () => fetchPermission(true), permissions };
};
